package cn.sdc.sfw.dao.handler.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import cn.sdc.sfw.dao.exception.DaoException;
import cn.sdc.sfw.dao.handler.BasicHandler;
import cn.sdc.sfw.dao.handler.DbHandler;
import cn.sdc.sfw.dao.handler.ResultSetHandler;
import cn.sdc.sfw.dao.handler.SelectHandler;

/**
 * @author sdc
 *  
 */
public class SelectHandlerImpl extends BasicHandler implements SelectHandler {

	private ResultSetHandler resultSetHandler_;

	private int fetchSize_ = 100;

	private int maxRows_ = -1;

	public SelectHandlerImpl() {
	}

	public SelectHandlerImpl(DataSource dataSource, String sql,
			ResultSetHandler resultSetHandler) {
		setDataSource(dataSource);
		setSql(sql);
		setResultSetHandler(resultSetHandler);
	}

	public ResultSetHandler getResultSetHandler() {
		return resultSetHandler_;
	}

	public void setResultSetHandler(ResultSetHandler resultSetHandler) {
		resultSetHandler_ = resultSetHandler;
	}

	public int getFetchSize() {
		return fetchSize_;
	}

	public void setFetchSize(int fetchSize) {
		fetchSize_ = fetchSize;
	}

	public int getMaxRows() {
		return maxRows_;
	}

	public void setMaxRows(int maxRows) {
		maxRows_ = maxRows;
	}

	public Object execute() throws DaoException {
		return execute(null, null);
	}
	
	public Object execute(Object[] args) throws DaoException {
		return execute(args, getArgTypes(args));
	}

	public Object execute(Object[] args, Class[] argTypes)
			throws DaoException {
		Connection con = getConnection();
		try {
			System.out.println("[START SQL]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
			System.out.println(getCompleteSql(args));
			System.out.println("[END   SQL]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
			return execute(con, args, argTypes);
		} catch (SQLException ex) {
			throw new DaoException(ex);
		} finally {
//			DbHandler.closeConnection(con);
		}
	}

	protected Object execute(Connection connection, Object[] args,
			Class[] argTypes) throws SQLException {

		PreparedStatement ps = null;
		try {
			ps = prepareStatement(connection);
			if(args != null && args.length > 0){
				bindArgs(ps, args, argTypes);
			}
			return execute(ps);
		} finally {
			DbHandler.closeStatement(ps);
		}
	}

	protected Object[] setup(Connection con, Object[] args) {
		return args;
	}

	protected PreparedStatement prepareStatement(Connection connection) {
		PreparedStatement ps = super.prepareStatement(connection);
		if (fetchSize_ > -1) {
			DbHandler.setFetchSize(ps, fetchSize_);
		}
		if (maxRows_ > -1) {
			DbHandler.setMaxRows(ps, maxRows_);
		}
		return ps;
	}

	protected Object execute(PreparedStatement ps) throws SQLException {
		if (resultSetHandler_ == null) {
			throw new DaoException(DaoException.NO_RESULT_SET_HANDLER);
		}
		ResultSet resultSet = null;
		try {
			resultSet = createResultSet(ps);
			return resultSetHandler_.handle(resultSet);
		} finally {
			DbHandler.closeResultSet(resultSet);
		}
	}

	protected ResultSet createResultSet(PreparedStatement ps) {
		return DbHandler.executeQuery(ps);
	}
}